#include"../source/server.hpp"

#include<string.h>
// int main()
// {
//     //创建服务端，开始监听，监听到了创建监听套接字，对监听套接字进行收发数据
//     Poller poller;
//     Socket lst_sock;
//     lst_sock.CreateServer(8888);
//     //为监听套接字，创建一个channel进行事件的管理，以及事件的处理
//     Channel channel (&poller,lst_sock.Fd());
//     //获取新链接，监控可读事件

//     while(1)
//     {
//         int newfd =lst_sock.Accept();
//         //if(newfd<0) continue;
//         Socket cli_sock(newfd);
//         char buf[1024] = {0};
//         int ret =cli_sock.Recv(buf,1023);
//         std::cout<<buf<<std::endl;
//         if(ret<0)
//         {
//             cli_sock.Close();
//             continue;
//         }
//         cli_sock.Send(buf,ret);
//         cli_sock.Close();
//     }
//     lst_sock.Close();
//     return 0;
    
// }
// using std::cout;
// using std::endl;
// void HandleCloce(Channel * channel){
//     std::cout<<"close"<<channel->Fd()<<endl;
//     channel->Remove();
//     delete channel;
// }
// void HandleRead(Channel * channel){
//     int fd =channel->Fd();
//     char buf[1024]={0};
//     int ret =recv(fd,buf,1023,0);
//     if(ret<=0){
//         return HandleCloce(channel);
//     }
//     channel->EnableWrite();
//     cout<<buf<<endl;

// }
// void HandleWrite(Channel * channel){
//     int fd =channel->Fd();
//     const char *data = "hello,nihao";
//     int ret = send(fd , data ,strlen(data),0);
//     if(ret<0)
//     {
//         return HandleCloce(channel); 
//     }
//     channel->DisableWrite();
// }
// void HandleError(Channel * channel){
//     return HandleCloce(channel);
// }
// void HandleEvnt(Channel * channel){
//     cout<<"有了一个新事件"<<endl;
// }
// void Acceptor (EventLoop *loop,Channel*lst_channel)
// {
//     int fd =lst_channel->Fd();
//     int newfd = accept(fd,NULL,NULL);//iofd
//     if(newfd<0){return;}
//     Channel *channel =new Channel(loop,newfd);
//     channel->SetReadCallback(std::bind(HandleRead,channel));
//     channel->SetWriteCallback(std::bind(HandleWrite,channel));
//     channel->SetCloseCallback(std::bind(HandleCloce,channel));
//     channel->SetErrorCallback(std::bind(HandleError,channel));
//     channel->SetEventCallback(std::bind(HandleEvnt,channel));
//     channel->EnableRead();
// }
// int main( )
// {
//     EventLoop loop;
//     Socket lst_sock;
//     lst_sock.CreateServer(8888);
//     Channel channel (&loop,lst_sock.Fd());
//     //设置可读事件回调，该回调直接接收监听，创建iofd，然后设置其它的回调
//     channel.SetReadCallback(std::bind(Acceptor,&loop,&channel));//回调中获取新链接，为新连接创建channel并且添加监控
    
//     channel.EnableRead();//启动可读事件，把可读事件添加到eventloop中去
//     //在这里，epoll_ctl进行事件的添加，接着事件依次触发，各事件依次启动。
//     while(1){
//         // std::vector<Channel*> actives;
//         // poller.Poll(&actives);//将就绪事件先存储起来，然后统一交给HandleEvent()就绪回调函数的调用
//         // //处理就绪事件
//         // //epoll只是提醒服务器，哪些事件就绪了，接着调用自己的方法去处理这些事件就好了
//         // for (auto &a:actives)
//         // {
//         //     /* code */
//         //     a->HandleEvent();
//         // }
//         // sleep(1);
//         loop.Start();

//     }
//     lst_sock.Close();
//     return 0;
// }

//TimerWheel
using std::cout;
using std::endl;
void HandleCloce(Channel * channel){
    DBG_LOG("close fd:%d",channel->Fd());
    channel->Remove();
    delete channel;
}
void HandleRead(Channel * channel){
    int fd =channel->Fd();
    char buf[1024]={0};
    int ret =recv(fd,buf,1023,0);
    if(ret<=0){
        return HandleCloce(channel);
    }
    DBG_LOG("read:%s",buf);
    channel->EnableWrite();
    

}
void HandleWrite(Channel * channel){
    int fd =channel->Fd();
    const char *data = "hello,nihao";
    int ret = send(fd , data ,strlen(data),0);
    if(ret<0)
    {
        return HandleCloce(channel); 
    }
    channel->DisableWrite();
}
void HandleError(Channel * channel){
    return HandleCloce(channel);
}
void HandleEvnt(EventLoop *loop,Channel * channel,uint64_t id){
    //刷新任务活跃度
    loop->TimerRefresh(id);
    cout<<"有了一个新事件"<<endl;
}
void Acceptor (EventLoop *loop,Channel*lst_channel)
{
    int fd =lst_channel->Fd();
    int newfd = accept(fd,NULL,NULL);//iofd
    if(newfd<0){return;}
    uint64_t timerid=rand()%10000;
    Channel *channel =new Channel(loop,newfd);
    channel->SetReadCallback(std::bind(HandleRead,channel));
    channel->SetWriteCallback(std::bind(HandleWrite,channel));
    channel->SetCloseCallback(std::bind(HandleCloce,channel));
    channel->SetErrorCallback(std::bind(HandleError,channel));
    channel->SetEventCallback(std::bind(HandleEvnt,loop,channel,timerid));
    channel->EnableRead();
    //非活跃连接的超时释放操作,10s后关闭连接
    //注意：定时销毁任务，必须在启动读事件之前，因为有可能启动了事件监控
    //立即有了事件，但这是还没有任务
    //非活跃连接：10s中没有数据通信的连接
    loop->TimerAdd(timerid,10,std::bind(HandleCloce,channel));
}
//timerwheel测试：为新链接添加了一个10s后定时销毁的任务，销毁的是非活跃任务
//因此每次有事件了，都要去刷新任务活跃度，其实就是定时任务的延迟执行
int main( )
{
    srand(time(NULL));
    EventLoop loop;
    Socket lst_sock;
    lst_sock.CreateServer(8888);
    Channel channel (&loop,lst_sock.Fd());
    //设置可读事件回调，该回调直接接收监听，创建iofd，然后设置其它的回调
    channel.SetReadCallback(std::bind(Acceptor,&loop,&channel));//回调中获取新链接，为新连接创建channel并且添加监控
    
    channel.EnableRead();//启动可读事件，把可读事件添加到eventloop中去
    //在这里，epoll_ctl进行事件的添加，接着事件依次触发，各事件依次启动。
    while(1){
        // std::vector<Channel*> actives;
        // poller.Poll(&actives);//将就绪事件先存储起来，然后统一交给HandleEvent()就绪回调函数的调用
        // //处理就绪事件
        // //epoll只是提醒服务器，哪些事件就绪了，接着调用自己的方法去处理这些事件就好了
        // for (auto &a:actives)
        // {
        //     /* code */
        //     a->HandleEvent();
        // }
        // sleep(1);
        loop.Start();

    }
    lst_sock.Close();
    return 0;
}